/**
 * 20240730最后修改
 * @author ljy
 * 不要使用下面的路由导入，因为会触发eslint的dependency cycle via错误，即A依赖的B中的内容 ，B中也依赖的A中的内容。
 * 原因是某个组件在router文件中已经作为组件被引入，然后那个组件又引入了本文件，从而导致循环依赖错误。
 * 因此不在路径中直接跳转到登录页面，改为重新登录提示
 * import { useRouter } from 'vue-router';
 */
import axios from 'axios';
import router from '@/router';
import pinia from '@/stores/pinia';
import { useAuthStore } from '@/stores/auth';

import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'; // element plus对话框
import { type ResponseData } from '@/types/interface/base_interface';
import useLoadingDialog from '@/api/common/loading';

//初始化axios的配置。这样设计的目的是为了在main.js中调用该函数来初始化，解决无法在axios中使用pinia的问题。
export function setupAxiosConfig() {
  //创建菜单的store对象
  // const authStore = useAuthStore();
  const authStore = useAuthStore(pinia);
  //引入自定义的加载框
  const { startLoading, endLoading } = useLoadingDialog();

  // 创建axios对象。
  const instance = axios.create({
    timeout: 50000, // 超时时间。正式发布要记得修改回正常超时时间
    responseType: 'json',
    headers: {
      'Content-Type': 'application/json;charset=UTF-8'
    }
  });

  // 添加请求拦截器
  instance.interceptors.request.use(
    (config) => {
      const token = authStore.getToken();
      if (token !== null) {
        if (typeof config.headers !== 'undefined') {
          if (token !== '' && token !== null && token !== undefined) {
            // config.headers.access_token = token; // 携带token
            config.headers.Authorization = `${token}`; // 携带token
          }
        }
      }
      const path = router.currentRoute.value.fullPath; // 获取当前路由的路径
      if (path !== '/login') {
        // 登陆页面不需要加载状态，由登录页面手动控制
        startLoading();
      }
      // 加载对话框，要考虑出现异常的情况
      // startLoading();
      return config;
    },
    (error) => Promise.resolve(error.response)
    // Promise.reject(error);
  );

  // 添加服务器响应拦截器
  instance.interceptors.response.use(
    (response) => {
      // 关闭加载对话框
      endLoading();
      const { data } = response; // 获取返回的数据
      // const path = router.currentRoute.value.fullPath; // 获取当前路由的路径
      // if (path !== '/login') { // 登陆页面不弹出错误信息，主要是针对vuex中的获取菜单权限设定
      // }
      if (data.success === false) {
        // 如果服务端返回的是错误数据
        if (typeof data.msg === 'string') {
          // 如果有返回错误信息
          ElMessage({
            message: data.msg,
            grouping: true,
            type: 'error'
          });
        }
      }
      /* if (data.code !== 0) { // 如果服务端返回的是错误数据
    if (data.code === 401) { // 如果是没有登陆的请求或是token错误
      // 清除登录的用户信息
      store.dispatch('logout');
      ElMessageBox.alert(data.msg, '系统提示', {
        confirmButtonText: '确认',
      }).then((res) => {
        // 跳转到登录页面
        router.push('/login');
      });
      // window.location.reload();
    } else { // 如果是其他错误信息
      if (typeof data.msg === 'string') { // 如果有返回错误信息
        ElMessage({
          message: data.msg,
          grouping: true,
          type: 'error',
        });
      }
    }
  } */
      // return response;
      return data; // 直接返回数据
    },
    (error) => {
      // 关闭加载对话框
      endLoading();
      //如果是从服务器返回的错误信息(与后端约定好的)
      if (error.response) {
        // 一般在服务器自定义了返回的http错误数据，就可以接收到。例如没有携带token或token非法
        const status = <number>error.response.status; // 获取服务端的http错误码
        const { data } = error.response; // 获取服务端响应数据
        let title = '服务器异常'; // 错误提示对话框的标题
        // 如果是下载流出错，会因为axios设置了header为blob类型，即便返回json数据也无法接收。
        if (Object.prototype.toString.call(data) !== '[object Blob]') {
          // 先判断是不是blob格式。如果是blob模式，则不弹出错信息，转由各个调用组件自己处理
          if (data.code === 401) {
            // 如果是token错误或未携带
            title = 'token缺失';
            // 清除登录的用户信息
            authStore.handleLogoutSuccess();
          } else {
            // 如果是其他异常
            title = '服务器异常';
          }
          if (status !== 406) {
            //如果是406异常，服务端设定为确认是否要强制删除记录（则不进行统一处理，由具体组件来设定业务）
            ElMessage({
              message: data.msg,
              type: 'error'
            });
          }
          // ElMessageBox.alert(data.msg, title, {
          //   confirmButtonText: '确认',
          // }).then((res) => {
          //   // 跳转到登录页面
          // });
        }
        // 将错误信息返回，并用resolve来调用，即全部放到正常逻辑中进行处理
        return Promise.resolve(error.response.data);
      } else {
        console.log(error);
        // 如果不是服务端自定义的错误状态码，例如服务端404，或是没有设置跨域导致的访问异常
        ElMessage({
          message: `服务器连接失败`,
          grouping: true,
          type: 'error'
        });
      }
      // 将错误信息返回
      return Promise.reject(error);
    }
  );
  return { instance };
}
